package com.bnz.config;

import com.bnz.service.impl.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;

/**
 * 配置类
 */
@Configuration // 配置类
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // 引入自己写的service
    @Autowired
    private MyUserDetailService userDetailsService;
    @Autowired
    private DataSource dataSource;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 1、自定义表单验证(resources/static/login.html)
        http.formLogin()
                // 2、定义登录页面
                .loginPage("/login.html")
                // 3、定义登录处理页面
                .loginProcessingUrl("/login")
                // 4、登录成功后会跳转的页面
                .successForwardUrl("/user/wecome")
                // 5、对所有的请求都放行（上面的）
                .permitAll()
                .and()
                // 6、其他的请求必须得到此处的验证
                .authorizeRequests()
                .anyRequest() // 请它请求
                .authenticated() // 经过此认证才能访问
                .and()
                // 7、对异常的处理
                .exceptionHandling().accessDeniedPage("/unauth.html")
                .and()
                // 8、添加remberMe功能
                .rememberMe()
                .tokenValiditySeconds(100) // 设置过期时间，秒为单位
                .tokenRepository(tokenRepository()) // 设置数据源
                .userDetailsService(userDetailsService()) // 设置对应的userDetailService
                .and()
                // 9、对csrf禁用
                .csrf().disable();


    }

    // 数据源(remember的数据源相关配置)
    private PersistentTokenRepository tokenRepository() {
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        jdbcTokenRepository.setDataSource(dataSource); // 设置数据源
        jdbcTokenRepository.setCreateTableOnStartup(true); // 启动时自动创建表
        return jdbcTokenRepository;
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().mvcMatchers("/WEBJARS/**");
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}
